package com.example.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.example.domain.message.MessageConstant;
import com.example.domain.pojo.Setmeal;
import com.example.domain.result.Result;
import com.example.domain.utils.DateUtils;
import com.example.service.MemberService;
import com.example.service.OrderService;
import com.example.service.SetMealService;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

//报表操作
@RestController
@RequestMapping("/report")
public class ReportController {

    @Autowired
    private MemberService memberService;

    @Autowired
    private SetMealService setMealService;

    @Autowired
    private OrderService orderService;

    //会员统计
    @RequestMapping("/getMemberReport")
    public Result getMemberReport(){
        //数据格式
        Map<String,Object> map=new HashMap<>();

        //过去一年的月份 日历对象
        Calendar calendar=Calendar.getInstance();//获得日历时间,模拟时间就是当前时间
        //计算过去12个月 正值 往前 负值 往后,在日历基础上添加几个月,跟现在的时间没有关系 2018-10
        calendar.add(Calendar.MONTH,-12);//获得当前时间往前推12个月的时间,最终会得到计算好的日历时间
        //月份的list集合
        List<String> months=new ArrayList<>();
        //遍历12次
        for (int i = 0; i < 12; i++) { //日历的当前月统计怎么办,往后+1
            //从12月份的往后推一个月开始查询 这个时候时间已经变成2018.10月份
            calendar.add(Calendar.MONTH,1);//2018.11
            //获得时间
            Date time = calendar.getTime();
            //格式化月份,将月份添加到集合
            months.add(new SimpleDateFormat("yyyy.MM").format(time));
        }
        map.put("months",months);
        //根据list集合作为条件查询会员数量
        List<Integer> count= null;
        try {
            count = memberService.findMemberCount(months);
        } catch (Exception e) {
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
        //将查询的每个月会员数量list添加到map集合中
        map.put("memberCount",count);
        return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);


    }

    //根据套餐查询套餐占比
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport(){
        /*

        "data":{"setmealNames":["套餐1","套餐2","套餐3"],  数组,根据查询的数组封装map集合

                "setmealCount":[{"name":"套餐1","value":10},  map集合;实体类封装不了,只能map集合
                                {"name":"套餐2","value":30},
                                {"name":"套餐3","value":25}
                                ] }
         */
        //套餐占比,有时间限制么
        try {
            Map allmap=new HashMap();
            //查询套餐名称
            List<Setmeal> namelist=setMealService.findMealName();
            List<String> names=new ArrayList<>();

            //存放套餐数量的map集合
            Map<String,Object> setmealcount=new HashMap<>();

            List<Map> mealmap=new ArrayList<>();
            for (Setmeal setmeal:namelist) {
                //将所有套餐的名称添加到集合中
                names.add(setmeal.getName());

                Map<String,Object> countMap=new HashMap<>();
                //根据套餐名称查询订单中订购套餐人数
                Integer id=setmeal.getId();
                System.out.println(setmeal.getId());


                Long count= orderService.findCount(id);
                //一个套餐的键值信息
                countMap.put("name",setmeal.getName());
                countMap.put("value",count);
                mealmap.add(countMap);
            }
            //将存有套餐名称的list集合存放在map集合中
            allmap.put("setmealNames",names);

            allmap.put("setmealCount",mealmap);
            return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,allmap);
        } catch (Exception e) {
            return new Result(false,MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData() throws Exception {
        /*
        reportDate:null,
        todayNewMember :0,新增会员数
        totalMember :0,总会员数
        thisWeekNewMember :0,本周新增会员数
        thisMonthNewMember :0,本月新增会员数
         */
        Map<String,Object> map=new HashMap<>();
        //1:以字符串形式获取当前日期
        String date = DateUtils.parseDate2String(new Date());
        map.put("reportDate",date);
        //2:今天新增会员数
        System.out.println(date);
        Long count=memberService.findMemberByDate(date);
        map.put("todayNewMember",count);
        //3:总会员数
        Long all= memberService.findAllCount();
        map.put("totalMember",all);
        //4:本周新增会员数,条件是一周的日期查询
        //4.1:根据当前日期得到一周的时间
        Date firstDayOfWeek = DateUtils.getThisWeekMonday(new Date());
        Date lastDayOfWeek = DateUtils.getSundayOfThisWeek();
        String first=DateUtils.parseDate2String(firstDayOfWeek);
        String last=DateUtils.parseDate2String(lastDayOfWeek);


        Map<String,String> week=new HashMap<>();
        week.put("first",first);
        week.put("last",last);
        Long weekcount=memberService.findcountWeek(week);
        map.put("thisWeekNewMember",weekcount);
        //5:本月新增会员数
        Date month_date = DateUtils.getFirstDay4ThisMonth();//获得本月一日的日期,也要获得当月最后一天的日期,字符串的切割还是用日历组件往后推
        String newmonth=DateUtils.parseDate2String(month_date);
        int k = newmonth.lastIndexOf("-");
        String s = newmonth.substring(0,k);
        Map<String,String> month=new HashMap<>();
        month.put("first",newmonth);
        month.put("last",s+"-31");
        Long monthcount=memberService.findMonth(month);
        map.put("thisMonthNewMember",monthcount);


        //5:todayOrderNumber :0,今日预约数
        Long newcount=orderService.findDateCount(date);
        map.put("todayOrderNumber",newcount);
        //5:todayVisitsNumber :0,今日到诊数
        Long visitdate=orderService.findvisitdate(date);
        map.put("todayVisitsNumber",visitdate);


        //7:thisWeekOrderNumber :0,本周预约数
        Long newWeekcount=orderService.findWeekCount(week);
        map.put("thisWeekOrderNumber",newWeekcount);


        //8:thisWeekVisitsNumber :0,本周到诊数
        Long visitWeekdate=orderService.findvisitWeek(week);
        map.put("thisWeekVisitsNumber",visitWeekdate);


        //9:thisMonthOrderNumber :0,本月预约数
        Long monthOrder= orderService.findWeekCount(month);
        map.put("thisMonthOrderNumber",monthOrder);

        //10:thisMonthVisitsNumber :0,本月到诊数
        Long monthVisitOrder= orderService.findvisitWeek(month);
        map.put("thisMonthVisitsNumber",monthVisitOrder);

        //存放热门套餐的集合
        Map<String,Object> hotmap=new HashMap<>();

        //排序查询套餐
        List<Map> list= setMealService.findMealHot();

        map.put("hotSetmeal",list);
        return new Result(true,MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);


    }

    //exportBusinessReport
    //导出运营分析表
    @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletResponse response, HttpServletRequest request) throws Exception {
        //导出成功,给出提示
        Result result = getBusinessReportData();
        if(!result.isFlag()){
            return null;
        }
        //将结果集中的数据取出来
        Map result_map = (Map) result.getData();
        //map集合的值根据键取值
        String reportDate = (String) result_map.get("reportDate");
        Long todayNewMember = (Long) result_map.get("todayNewMember");
        Long totalMember = (Long) result_map.get("totalMember");
        Long thisWeekNewMember = (Long) result_map.get("thisWeekNewMember");
        Long thisMonthNewMember = (Long) result_map.get("thisMonthNewMember");
        Long todayOrderNumber = (Long) result_map.get("todayOrderNumber");
        Long todayVisitsNumber = (Long) result_map.get("todayVisitsNumber");
        Long thisWeekOrderNumber = (Long) result_map.get("thisWeekOrderNumber");
        Long thisWeekVisitsNumber = (Long) result_map.get("thisWeekVisitsNumber");
        Long thisMonthOrderNumber = (Long) result_map.get("thisMonthOrderNumber");
        Long thisMonthVisitsNumber = (Long) result_map.get("thisMonthVisitsNumber");

        //获得Excel模板文件绝对路径 部署项目路径写法不一样,window和linux环境不一样
        String temlateRealPath = request.getSession().getServletContext().getRealPath("template") + File.separator + "report_template.xlsx";//File.separator 代表/

        //1:将获取到的数据写入文档中,需要的数据是上一个controller的方法中map集合中的数据
        //调用方法么 在controller返回一个写好的文档,文档在控制层用输出流的方式返回
        try {
            //基于提供的模板文件在内存中创建一个excel表格对象
            XSSFWorkbook excel=new XSSFWorkbook(new File(temlateRealPath));
            //创建sheet表格
            XSSFSheet sheetAt = excel.getSheetAt(0);
            //根究表格创建单元格 是按照模板的行和列写书数据,就是创建的行和列是指定的
            //第0行是标题 最后将数据写入磁盘文件中,需要与模板表格一一对比
            XSSFRow row2 = sheetAt.getRow(2);
            row2.getCell(5).setCellValue(reportDate);
            //表格中不能读取整数,但是可以写入整型
            XSSFRow row4 = sheetAt.getRow(4);
            row4.getCell(5).setCellValue(todayNewMember);
            row4.getCell(7).setCellValue(totalMember);

            XSSFRow row5 = sheetAt.getRow(5);
            row5.getCell(5).setCellValue(thisWeekNewMember);
            row5.getCell(7).setCellValue(thisMonthNewMember);

            XSSFRow row6 = sheetAt.getRow(7);
            row6.getCell(5).setCellValue(todayOrderNumber);
            row6.getCell(7).setCellValue(todayVisitsNumber);

            XSSFRow row7 = sheetAt.getRow(8);
            row7.getCell(5).setCellValue(thisWeekOrderNumber);
            row7.getCell(7).setCellValue(thisWeekVisitsNumber);


            XSSFRow row8 = sheetAt.getRow(9);
            row8.getCell(5).setCellValue(thisMonthOrderNumber);
            row8.getCell(7).setCellValue(thisMonthVisitsNumber);

            List<Map> hotSetmeal = (List<Map>) result_map.get("hotSetmeal");

            //list有多少条记录,就创建多少行数据
            for (int i = 0; i <hotSetmeal.size(); i++) {
                XSSFRow newRows = sheetAt.getRow(12+i);
                for (Map map : hotSetmeal) {

                        String name = (String) map.get("name");
                        newRows.getCell(4).setCellValue(name);
                        Long setmeal_count = (Long) map.get("setmeal_count");
                        newRows.getCell(5).setCellValue(setmeal_count);
                        BigDecimal proportion = (BigDecimal) map.get("proportion");
                        newRows.getCell(6).setCellValue(proportion.doubleValue());


                }
            }

            //告诉浏览器,返回的什么类型的数据
            response.setContentType("application/vnd.ms-excel");
            //响应头作用:用户下载提供默认的文件名content-Disposition, 文件以附件的形式下载:attachment,文件名称filename=report.xlsx
            response.setHeader("content-Disposition", "attachment;filename=report.xlsx");
            //使用输出流进行表格下载,基于浏览器作为客户端下载
            ServletOutputStream os = response.getOutputStream();

            excel.write(os);
            os.flush();
            excel.close();
            return null;

        } catch (IOException e) {
            return new Result(false,"文件导出失败");
        }


    }


}
